package cn.iocoder.yudao.module.eval.service.monitoring;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.eval.controller.admin.monitoring.vo.EvalMonitoringDataPageReqVO;
import cn.iocoder.yudao.module.eval.controller.admin.monitoring.vo.EvalMonitoringDataSaveReqVO;
import cn.iocoder.yudao.module.eval.dal.dataobject.monitoring.EvalMonitoringDataDO;
import cn.iocoder.yudao.module.eval.dal.mysql.monitoring.EvalMonitoringDataMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.eval.enums.ErrorCodeConstants.*;

/**
 * 评价实施监控 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
@Slf4j
public class EvalMonitoringDataServiceImpl implements EvalMonitoringDataService {

    @Resource
    private EvalMonitoringDataMapper monitoringDataMapper;

    @Override
    public Long createMonitoringData(EvalMonitoringDataSaveReqVO createReqVO) {
        // 插入
        EvalMonitoringDataDO monitoringData = BeanUtils.toBean(createReqVO, EvalMonitoringDataDO.class);
        monitoringData.setMonitorTime(LocalDateTime.now());
        monitoringDataMapper.insert(monitoringData);
        // 返回
        return monitoringData.getId();
    }

    @Override
    public void updateMonitoringData(EvalMonitoringDataSaveReqVO updateReqVO) {
        // 校验存在
        validateMonitoringDataExists(updateReqVO.getId());
        // 更新
        EvalMonitoringDataDO updateObj = BeanUtils.toBean(updateReqVO, EvalMonitoringDataDO.class);
        monitoringDataMapper.updateById(updateObj);
    }

    @Override
    public void deleteMonitoringData(Long id) {
        // 校验存在
        validateMonitoringDataExists(id);
        // 删除
        monitoringDataMapper.deleteById(id);
    }

    private void validateMonitoringDataExists(Long id) {
        if (monitoringDataMapper.selectById(id) == null) {
            throw exception(MONITORING_DATA_NOT_EXISTS);
        }
    }

    @Override
    public EvalMonitoringDataDO getMonitoringData(Long id) {
        return monitoringDataMapper.selectById(id);
    }

    @Override
    public List<EvalMonitoringDataDO> getMonitoringDataList(Collection<Long> ids) {
        return monitoringDataMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<EvalMonitoringDataDO> getMonitoringDataPage(EvalMonitoringDataPageReqVO pageReqVO) {
        return monitoringDataMapper.selectPage(pageReqVO);
    }

    @Override
    public List<EvalMonitoringDataDO> getMonitoringDataListByPlanId(Long planId) {
        return monitoringDataMapper.selectListByPlanId(planId);
    }

    @Override
    public List<EvalMonitoringDataDO> getMonitoringDataListBySubjectId(Long subjectId) {
        return monitoringDataMapper.selectListBySubjectId(subjectId);
    }

    @Override
    public List<EvalMonitoringDataDO> getMonitoringDataListByMonitorType(String monitorType) {
        return monitoringDataMapper.selectListByMonitorType(monitorType);
    }

    @Override
    public void handleMonitoringException(Long id, String handleResult) {
        // 校验存在
        validateMonitoringDataExists(id);

        // 更新处理状态
        EvalMonitoringDataDO updateObj = new EvalMonitoringDataDO();
        updateObj.setId(id);
        updateObj.setHandleStatus(1); // 已处理
        updateObj.setHandleTime(LocalDateTime.now());
        updateObj.setHandleResult(handleResult);
        monitoringDataMapper.updateById(updateObj);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchCreateMonitoringData(List<EvalMonitoringDataSaveReqVO> monitoringDataList) {
        for (EvalMonitoringDataSaveReqVO monitoringDataReqVO : monitoringDataList) {
            createMonitoringData(monitoringDataReqVO);
        }
    }

    @Override
    public Object getMonitoringStatistics(Long planId) {
        List<EvalMonitoringDataDO> monitoringDataList = getMonitoringDataListByPlanId(planId);
        
        Map<String, Object> statistics = new HashMap<>();
        statistics.put("totalCount", monitoringDataList.size());
        
        // 按状态统计
        Map<String, Long> statusCount = new HashMap<>();
        statusCount.put("normal", monitoringDataList.stream().filter(data -> data.getMonitorStatus() == 0).count());
        statusCount.put("exception", monitoringDataList.stream().filter(data -> data.getMonitorStatus() == 1).count());
        statusCount.put("warning", monitoringDataList.stream().filter(data -> data.getMonitorStatus() == 2).count());
        statistics.put("statusCount", statusCount);
        
        // 按类型统计
        Map<String, Long> typeCount = new HashMap<>();
        typeCount.put("attendance", monitoringDataList.stream().filter(data -> "attendance".equals(data.getMonitorType())).count());
        typeCount.put("evaluator", monitoringDataList.stream().filter(data -> "evaluator".equals(data.getMonitorType())).count());
        typeCount.put("supervisor", monitoringDataList.stream().filter(data -> "supervisor".equals(data.getMonitorType())).count());
        typeCount.put("overall", monitoringDataList.stream().filter(data -> "overall".equals(data.getMonitorType())).count());
        statistics.put("typeCount", typeCount);
        
        return statistics;
    }

}
